package com.noble.glamour.ui.qiniu.play;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.noble.glamour.R;
import com.noble.library.base.BaseAppCompatActivity;
import com.noble.library.utils.ScreenUtils;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;
import com.pili.pldroid.player.widget.PLVideoView;
import com.qiniu.shortvideo.play.PLPlayMgr;
import com.qiniu.shortvideo.utils.PLConstant;
import com.qiniu.shortvideo.utils.PLUtils;

/**
 * 短视频播放页, 上传页
 * Created by Su on 2017/11/10.
 */
public class PLPlayActivity extends BaseAppCompatActivity implements View.OnClickListener {
    private PLVideoTextureView mVideoView;          // 实现媒体播放功能，内部封装了PLMediaPlayer提供的播放功能
    private String mVideoPath;                      // 播放文件地址

    private LinearLayout footContainer;
    private PLPlayFootPanel footPanel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pl_short_play);

        RelativeLayout header = (RelativeLayout) findViewById(R.id.video_header);
        header.setPadding(0, ScreenUtils.getStatusBarHeight(this), 0, 0);
        findViewById(R.id.btn_close).setOnClickListener(this);

        mVideoView = (PLVideoTextureView) findViewById(R.id.video);
        mVideoPath = getIntent().getStringExtra(PLConstant.VIDEO_PLAY_PATH);
        mVideoView.setLooping(true);
//        mVideoView.setCoverView(view);     // 设置播放封面图片
        mVideoView.setAVOptions(PLPlayMgr.getInstance().getOptions()); // 配置播放参数

        // http://shortvideo.pdex-service.com/FgLP8D4z-IWN3ZGQsAEB8Zbh1mKB
        mVideoView.setVideoPath("http://shortvideo.pdex-service.com/Flm_s27rPf6whx80tMXTepzyTb4d");         // 设置播放地址

        // 设置加载动画， 在播放器进入缓冲状态时，自动显示加载界面，缓冲结束后，自动隐藏加载界面
        View loadingView = findViewById(R.id.loading_view);
        mVideoView.setBufferingIndicator(loadingView);

        // 4.3.5 设置播放状态监听器, SDK提供了丰富的播放状态消息回调
        mVideoView.setOnInfoListener(mOnInfoListener);
        mVideoView.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);
        mVideoView.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
        mVideoView.setOnCompletionListener(mOnCompletionListener);
        mVideoView.setOnErrorListener(mOnErrorListener);

        // 音视频数据回调监听
        mVideoView.setOnVideoFrameListener(mOnVideoFrameListener);
        mVideoView.setOnAudioFrameListener(mOnAudioFrameListener);

        // 设置画面预览模式： 包括：原始尺寸、适应屏幕、全屏铺满、16:9、4:3 等
        mVideoView.setDisplayAspectRatio(PLVideoView.ASPECT_RATIO_ORIGIN);

        footContainer = (LinearLayout) findViewById(R.id.foot_panel);
        footPanel = new PLPlayFootPanel(this);
        footContainer.addView(footPanel.getContentView());
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_close:
                finish();
                break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mVideoView.pause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mVideoView.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mVideoView.stopPlayback();
    }

    /**
     * 获取视频数据回调对象
     * <p>
     * 播放支持将解码后的音视频数据回调出来
     */
    private PLMediaPlayer.OnVideoFrameListener mOnVideoFrameListener = new PLMediaPlayer.OnVideoFrameListener() {

        /**
         * 回调一帧视频帧数据
         *
         * @param data   视频帧数据
         * @param size   数据大小
         * @param width  视频帧的宽
         * @param height 视频帧的高
         * @param format 视频帧的格式，0代表 YUV420P，1 代表 JPEG， 2 代表 SEI
         * @param ts     时间戳，单位是毫秒
         */
        @Override
        public void onVideoFrameAvailable(byte[] data, int size, int width, int height, int format, long ts) {
            PLUtils.log("onVideoFrameAvailable: " + size + ", " + width + " x " + height + ", " + format + ", " + ts);
        }
    };

    /**
     * 获取音频数据回调对象
     */
    private PLMediaPlayer.OnAudioFrameListener mOnAudioFrameListener = new PLMediaPlayer.OnAudioFrameListener() {

        /**
         * 回调一帧音频帧数据
         *
         * @param data   音频帧数据
         * @param size   数据大小
         * @param samplerate 采样率
         * @param channels 通道数
         * @param datawidth 位宽，目前默认转换为了16bit位宽
         * @param ts     时间戳，单位是毫秒
         */
        @Override
        public void onAudioFrameAvailable(byte[] data, int size, int samplerate, int channels, int datawidth, long ts) {
            PLUtils.log("onAudioFrameAvailable: " + size + ", " + samplerate + ", " + channels + ", " + datawidth + ", " + ts);
        }
    };

    /**
     * 监听播放器的状态消息，在播放器启动后，SDK会在播放器发生状态变化时调用该对象的
     * onInfo方法，同步状态信息
     * <p>
     * what定义了消息类型，extra是附加参数
     * <p>
     * 详情参看 5.2.2 {@see 'https://developer.qiniu.com/pili/sdk/1210/the-android-client-sdk?ref=www.qiniu.com'}
     */
    private PLMediaPlayer.OnInfoListener mOnInfoListener = new PLMediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(PLMediaPlayer plMediaPlayer, int what, int extra) {
            PLUtils.log("OnInfo, what = " + what + ", extra = " + extra);
            switch (what) {
                case PLMediaPlayer.MEDIA_INFO_BUFFERING_START:
                    break;
                case PLMediaPlayer.MEDIA_INFO_BUFFERING_END:
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                    PLUtils.log("first video render time: " + extra + "ms");
                    break;
                case PLMediaPlayer.MEDIA_INFO_AUDIO_RENDERING_START:
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_FRAME_RENDERING:
                    PLUtils.log("video frame rendering, ts = " + extra);
                    break;
                case PLMediaPlayer.MEDIA_INFO_AUDIO_FRAME_RENDERING:
                    PLUtils.log("audio frame rendering, ts = " + extra);
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_GOP_TIME:
                    PLUtils.log("Gop Time: " + extra);
                    break;
                case PLMediaPlayer.MEDIA_INFO_SWITCHING_SW_DECODE:
                    PLUtils.log("Hardware decoding failure, switching software decoding!");
                    break;
                case PLMediaPlayer.MEDIA_INFO_METADATA:
                    // 获取当前播放流的 METADATA 信息
                    PLUtils.log(mVideoView.getMetadata().toString());
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_BITRATE:
                case PLMediaPlayer.MEDIA_INFO_VIDEO_FPS:
                    PLUtils.log("FPS: " + extra);
                    break;
                case PLMediaPlayer.MEDIA_INFO_CONNECTED:
                    PLUtils.log("Connected !");
                    break;
                case PLMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED:
                    PLUtils.log("Rotation Changed: " + extra);

                    // 设置画面旋转（ 0度，90度，180度，270度旋转）
                    mVideoView.setDisplayOrientation(360 - extra);
                    break;
                default:
                    break;
            }
            return true;
        }
    };

    /**
     * 错误信息回调
     * <p>
     * 错误码参看{@see 'https://developer.qiniu.com/pili/sdk/1210/the-android-client-sdk?ref=www.qiniu.com'}
     */
    private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(PLMediaPlayer mp, int errorCode) {
            PLUtils.log("Error happened, errorCode = " + errorCode);
            switch (errorCode) {
                case PLMediaPlayer.ERROR_CODE_IO_ERROR:
                    /**
                     * SDK will do reconnecting automatically
                     */
                    PLUtils.log("IO Error!");
                    return false;
                case PLMediaPlayer.ERROR_CODE_OPEN_FAILED:
                    PLUtils.log("failed to open player !");
                    break;
                case PLMediaPlayer.ERROR_CODE_SEEK_FAILED:
                    PLUtils.log("failed to seek !");
                    break;
                default:
                    PLUtils.log("unknown error !");
                    break;
            }
            finish();
            return true;
        }
    };

    /**
     * 监听播放结束的消息，该回调的时机
     * <p>
     * 1，如果是播放文件，这是播放到文件结束后产生回调
     * 2，如果是在线视频，则会在读取到码流的EOF信息后产生回调，回调前会先播放完已缓冲的数据
     * 3，如果播放过程中产生onError，并且没有处理的话，最后也会回调本接口
     * 4，如果播放前设置了 setLooping(true), 则播放结束后会自动重新开始，不会回调本接口
     */
    private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(PLMediaPlayer plMediaPlayer) {
            PLUtils.log("Play Completed !");
            finish();
        }
    };

    /**
     * 监听当前播放器已经缓冲的数据量占整个视频时长的百分比，在播放直播流中无效，
     * 仅在播放文件和回放时才有效
     */
    private PLMediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new PLMediaPlayer.OnBufferingUpdateListener() {
        @Override
        public void onBufferingUpdate(PLMediaPlayer plMediaPlayer, int precent) {
            PLUtils.log("onBufferingUpdate: " + precent);
        }
    };

    /**
     * 监听当前播放的视频流的尺寸信息，在SDK解析出视频的尺寸信息后，会触发该回调
     * 可以在该回调中调整UI的视图尺寸
     */
    private PLMediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = new PLMediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(PLMediaPlayer plMediaPlayer, int width, int height) {
            PLUtils.log("onVideoSizeChanged: width = " + width + ", height = " + height);
        }
    };
}
